package cc.eddic.practice.spring.webapi;


import cc.eddic.practice.spring.domain.Option;
import cc.eddic.practice.spring.domain.Question;
import cc.eddic.practice.spring.domain.SubCategory;
import cc.eddic.practice.spring.dto.*;
import cc.eddic.practice.spring.repository.QuestionRepository;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.transaction.Transactional;
import java.util.Comparator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/api/questions")
public class QuestionRestController {

    private final QuestionRepository repository;

    public QuestionRestController(QuestionRepository repository){
        this.repository=repository;
    }

    @PostMapping
    public HttpEntity<?> add(@RequestBody final QuestionAddRequest model){
        val question=repository.save(model.as());
        return ResponseEntity.created(ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(question.getId()).toUri()).build();
    }

    @GetMapping("/{id}")
    public HttpEntity<QuestionResponse> get(@PathVariable("id") final long id){
        if(log.isDebugEnabled()) log.debug("id={}",id);
        val question=repository.findById(id).orElseThrow(NoSuchElementException::new);
        return ResponseEntity.ok(QuestionResponse.from(question));
    }

    @DeleteMapping("/{id}")
    public HttpEntity<?> del(@PathVariable("id") final long id){
        repository.deleteById(id);
        return ResponseEntity.noContent().build();
    }

    @GetMapping
    public HttpEntity<List<QuestionResponse>> getAll(){
        val questions=repository.findAll().stream().map(QuestionResponse::from).collect(Collectors.toList());
        return ResponseEntity.ok(questions);
    }

    @Transactional
    @PostMapping("/{questionID}/options")
    public HttpEntity<?> add(@PathVariable("questionID") Long questionID, @RequestBody final OptionAddRequest model){
        val question =repository.findById(questionID).orElseThrow(NoSuchElementException::new);//根据add方法的输入参数确定 要插入的subcategory属于那个category
        val option=model.as();//根据add方法的输入参数 创建subcategory的对象
        question.add(option);//把subcategory添加到category存储的subcategory的列表中
        repository.save(question);//添加

        val id = question.getOptions().stream()
                .filter(x->x.getChoice()==(model.getChoice()))
                .sorted(Comparator.comparing(Option::getCreatedOn).reversed())
                .map(Option::getId)
                .findFirst().orElse(-1L);
        if(log.isDebugEnabled()){
            log.debug("option id{}",option.getId());
            log.debug("(filter) option id {}",id);
        }
        //返回添加后生成的网址
        return ResponseEntity.created(ServletUriComponentsBuilder.fromCurrentRequest().path("/{questionID}/options/{optionID}").buildAndExpand(question.getId(),option.getId()).toUri()).build();
    }

    @GetMapping("/{questionID}/options/{optionID}")
    public HttpEntity<?> get(@PathVariable("questionID") Long questionID,@PathVariable("optionID") Long optionID){
        val question=repository.findById(questionID).orElseThrow(NoSuchElementException::new);
        val option=question.getOptions().stream().filter(option1 -> option1.getId().equals(optionID)).findFirst().orElseThrow(NoSuchElementException::new);
        return ResponseEntity.ok(OptionResponse.from(option));
    }

    @GetMapping("/{questionID}/options")
    public HttpEntity<?> get(@PathVariable("questionID") Long questionID){
        val question=repository.findById(questionID).orElseThrow(NoSuchElementException::new);
        return ResponseEntity.ok(question.getOptions().stream().map(OptionResponse::from).collect(Collectors.toList()));
    }
}
